using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Commands;
using uTorrentNetClient.ModelDesign.Contracts;
using uTorrentNetClient.ModelDesign.Events;
using uTorrentNetClient.ModelDesign.FileHandling;
using uTorrentNetClient.ModelDesign.Helper;
using System.Linq;
using uTorrentNetClient.ModelDesign.OptionalConverter;

namespace uTorrentNetClient.ModelDesign.EditSettings.Model
{
    public class EditSettingsModel : Base, IEditSettingsModel
    {
        private readonly IEventAggregator _eventAggregator;

        private List<SettingsGroupMapping> _allGroupMappingList;

        public IEditSettingsView View { get; set; }


        public DelegateCommand<object> OkCommand { get; set; }
        public DelegateCommand<object> CancelCommand { get; set; }
        public DelegateCommand<object> AddGroupCommand { get; set; }
        public DelegateCommand<object> DelGroupCommand { get; set; }
        public DelegateCommand<object> ClearGroupCommand { get; set; }

        private ObservableCollection<SettingsGroupMapping> _groupMappingCollection;
        public ObservableCollection<SettingsGroupMapping> GroupMappingCollection
        {
            get { return _groupMappingCollection; }
            set
            {
                _groupMappingCollection = value;
                SetNotifyPropertyChanged("GroupMappingCollection");
            }
        }

        private ObservableCollection<GroupMappingHelper> _mappingGroups;
        public ObservableCollection<GroupMappingHelper> MappingGroups
        {
            get { return _mappingGroups; }
            set
            {
                _mappingGroups = value;
                SetNotifyPropertyChanged("MappingGroups");
            }
        }

        private ObservableCollection<ConverterType> _converterTypes;
        public ObservableCollection<ConverterType> ConverterTypes
        {
            get { return _converterTypes; }
            set
            {
                _converterTypes = value;
                SetNotifyPropertyChanged("ConverterTypes");
            }
        }

        private ObservableCollection<SettingsValueType> _valueTypes;
        public ObservableCollection<SettingsValueType> ValueTypes
        {
            get { return _valueTypes; }
            set
            {
                _valueTypes = value;
                SetNotifyPropertyChanged("ValueTypes");
            }
        }
        
        private SettingsGroupMapping _selectedMapping;
        public SettingsGroupMapping SelectedMapping
        {
            get { return _selectedMapping; }
            set
            {
                _selectedMapping = value;
                setGroupProps(value);
                SetNotifyPropertyChanged("SelectedMapping");
            }
        }

        private string _selectedGroupText;
        public string SelectedGroupText
        {
            get { return _selectedGroupText; }
            set
            {
                _selectedGroupText = value;
                SetNotifyPropertyChanged("SelectedGroupText");
            }
        }

        private int _selectedGroupPosition;
        public int SelectedGroupPosition
        {
            get { return _selectedGroupPosition; }
            set
            {
                _selectedGroupPosition = value;
                SetNotifyPropertyChanged("SelectedGroupPosition");
            }
        }

        private GroupMappingHelper _selectedMappingGroup;
        public GroupMappingHelper SelectedMappingGroup
        {
            get { return _selectedMappingGroup; }
            set
            {
                _selectedMappingGroup = value;
                setGroup(value);
                SetNotifyPropertyChanged("SelectedMappingGroup");
            }
        }

        private GroupMappingHelper _selectedMainMappingGroup;
        public GroupMappingHelper SelectedMainMappingGroup
        {
            get { return _selectedMainMappingGroup; }
            set
            {
                _selectedMainMappingGroup = value;
                setMainMappingGroup(_selectedMainMappingGroup);
                SetNotifyPropertyChanged("SelectedMainMappingGroup");
            }
        }


        public EditSettingsModel(IEditSettingsView view, IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator;
            View = view;
            View.DataContext = this;

            GroupMappingCollection = new ObservableCollection<SettingsGroupMapping>();
            MappingGroups = new ObservableCollection<GroupMappingHelper>();
            ConverterTypes = new ObservableCollection<ConverterType>();
            ValueTypes = new ObservableCollection<SettingsValueType>();

            _allGroupMappingList = new List<SettingsGroupMapping>();

            OkCommand = new DelegateCommand<object>(okCommandExecute);
            CancelCommand = new DelegateCommand<object>(cancelCommandExecute);
            AddGroupCommand = new DelegateCommand<object>(addGroupCommandExecute);
            DelGroupCommand = new DelegateCommand<object>(delGroupCommandExecute);
            ClearGroupCommand = new DelegateCommand<object>(clearGroupCommandExecute);


            ConverterTypes.Clear();
            foreach (var cType in Enum.GetValues(typeof(ConverterType)))
            {
                ConverterTypes.Add((ConverterType)cType);
            }

            ValueTypes.Clear();
            foreach (var vType in Enum.GetValues(typeof(SettingsValueType)))
            {
                ValueTypes.Add((SettingsValueType)vType);
            }
        }


        public void SetMapping(List<SettingsGroupMapping> mappingList)
        {
            _allGroupMappingList.Clear();
            foreach (var mapping in mappingList)
            {
                _allGroupMappingList.Add(mapping);

                if (MappingGroups.Count(x => x.GroupName == mapping.Group) <= 0)
                    MappingGroups.Add(new GroupMappingHelper { GroupName = mapping.Group, Position = mapping.GroupPosition });
            }
        }

        private void saveSettingsMapping()
        {
            try
            {
                var path = Path.Combine(new ConfigurationHandling.ConfigRepository().SettingsPath, "SettingsGroupMapping.xml");

                FileHandler.SaveToXML(_allGroupMappingList, path);
            }
            catch (Exception ex)
            {
            }
        }

        private void setGroup(GroupMappingHelper group)
        {
            SelectedGroupText = SelectedMappingGroup.GroupName;
            SelectedGroupPosition = SelectedMappingGroup.Position;

            SelectedMapping.Group = SelectedMappingGroup.GroupName;
            SelectedMapping.GroupPosition = SelectedMappingGroup.Position;
        }

        private void setGroupProps(SettingsGroupMapping group)
        {
            var g = MappingGroups.FirstOrDefault(x => x.GroupName == group.Group);

            if (g != null && g != SelectedMappingGroup)
                SelectedMappingGroup = g;
        }

        private void setMainMappingGroup(GroupMappingHelper group)
        {
            GroupMappingCollection.Clear();
            foreach (var item in _allGroupMappingList.Where(x => x.Group == group.GroupName))
            {
                GroupMappingCollection.Add(item);
            }
        }

        #region Commands

        private void okCommandExecute(object o)
        {
            saveSettingsMapping();
            _eventAggregator.GetEvent<CloseEditSettingsEvent>().Publish(null);
        }

        private void cancelCommandExecute(object o)
        {
            _eventAggregator.GetEvent<CloseEditSettingsEvent>().Publish(null);
        }

        private void addGroupCommandExecute(object o)
        {
            var g = MappingGroups.FirstOrDefault(x => x.GroupName == SelectedGroupText);

            if (g != null)
                g.Position = SelectedGroupPosition;
            else
            {
                MappingGroups.Add(new GroupMappingHelper { GroupName = SelectedGroupText, Position = SelectedGroupPosition });
            }
        }

        private void delGroupCommandExecute(object o)
        {
            var g = MappingGroups.FirstOrDefault(x => x.GroupName == SelectedGroupText);

            if(g != null)
            {
                MappingGroups.Remove(g);

                var name = "Undefiniert";
                var pos = 1001;

                foreach(var group in _allGroupMappingList.Where(x => x.Group == SelectedGroupText))
                {
                    group.Group = name;
                    group.GroupPosition = pos;

                    if (MappingGroups.Count(x => x.GroupName == name) <= 0)
                    {
                        MappingGroups.Add(new GroupMappingHelper { GroupName = name, Position = pos });
                    }
                }
            }
        }

        private void clearGroupCommandExecute(object o)
        {
            SelectedGroupText = string.Empty;
            SelectedGroupPosition = 0;
        }

        #endregion
    }
}